unit avk_netmessages;

{$mode delphi}
{$codepage UTF8}

interface

uses
  Classes, avk_server, lNet;

const
  avk_StartServerTurn: Longint = 100;
type

  avk_TServerTurn = class (TObject)
  public
    TurnCorrect: boolean;
    Turn: Longword;//4294967295
  end;

  { avk_TClientSocket }

  avk_TClientSocket = class (TObject)
  public
    Turn: avk_TServerTurn;
    Id: Word;
    Socket: TLSocket;
  public
    constructor Create;
  end;

  { avk_TStackServer }

  avk_TStackServer = class (avk_TServer)
  private
    FSocketList: TStringList;
    FNoDelete: Boolean;
    function GetClientSocket(Index: String): avk_TClientSocket;
    function GetClientSocketById(Index: Integer): avk_TClientSocket;
    procedure DeleteClientSocketById(Index: Integer);
  private
    Turn: avk_TServerTurn;
    procedure OnAc(aSocket: TLSocket);
    procedure OnDs(aSocket: TLSocket);
  public
    property SocketsList: TStringList read FSocketList;
    property ClientSocket[Index: String]: avk_TClientSocket read GetClientSocket;
    property ClientSocketId[Index: Integer]: avk_TClientSocket read GetClientSocketById;
  public
    //function SayAllClient(aData: String): boolean; overload;
    //function SayAllClient(aData: ): boolean; overload;
  public
    constructor Create(aPort: Integer);
  end;


implementation

{ avk_TClientSocket }

constructor avk_TClientSocket.Create;
begin
  Turn := avk_TServerTurn.Create;
  Id := 0;
end;

{ avk_TStackServer }

function avk_TStackServer.GetClientSocket(Index: String): avk_TClientSocket;
var
  i : Integer;
  MemDel: Boolean;
begin
  MemDel := FNoDelete;
  FNoDelete := true;
  Result := nil;
  i := 0;
  while i < FSocketList.Count - 1 do begin
    if FSocketList.Strings[i] = Index then
      Result := avk_TClientSocket(FSocketList.Objects[i]);
    Inc( i );
  end;
  FNoDelete:=MemDel;
end;

function avk_TStackServer.GetClientSocketById(Index: Integer): avk_TClientSocket;
var
  i : Integer;
  MemDel: Boolean;
begin
  MemDel := FNoDelete;
  FNoDelete := true;
  Result := nil;
  i := 0;
  while i < FSocketList.Count - 1 do begin
    if avk_TClientSocket(FSocketList.Strings[i]).Id = Index then
      begin
        Result := avk_TClientSocket(FSocketList.Objects[i]);
        Break;
      end;
    Inc( i );
  end;
  FNoDelete:=MemDel;
end;

procedure avk_TStackServer.DeleteClientSocketById(Index: Integer);
var
  i : Integer;
begin
  if FSocketList.Count < 1 then Exit;
  i := 0;
  while i < FSocketList.Count do
    if avk_TClientSocket(FSocketList.Objects[i]).Id = Index then begin
      while FNoDelete do begin
        //просто ждем
      end;
      avk_TClientSocket(FSocketList.Objects[i]).Destroy;
      FSocketList.Objects[i] := nil;
      FSocketList.Delete(i);
    end else begin
      INC(i,1);
    end;
end;
procedure avk_TStackServer.OnAc(aSocket: TLSocket);
var
  NewClient: avk_TClientSocket;
begin
  NewClient := avk_TClientSocket.Create;
  NewClient.Id := aSocket.Handle;
  NewClient.Socket := aSocket;
  FSocketList.AddObject(AnsiToUtf8('[' + aSocket.PeerAddress + ']:[' + loc_IntToStr(aSocket.Handle) + ']'), NewClient);
  inherited OnAc(aSocket);
end;

procedure avk_TStackServer.OnDs(aSocket: TLSocket);
begin
  DeleteClientSocketById(aSocket.Handle);
  inherited OnDs(aSocket);
end;

constructor avk_TStackServer.Create(aPort: Integer);
begin
  FSocketList := TStringList.Create;
  FSocketList.Sorted := true;
  Turn:= avk_TServerTurn.Create;
  Turn.Turn := avk_StartServerTurn;
  Turn.TurnCorrect := false;

  inherited Create(aPort);
end;

end.

